package edu.rmit.client;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

import edu.rmit.contant.RoleType;
import edu.rmit.domain.Message;
import edu.rmit.domain.User;
import edu.rmit.service.IChatCallBackService;
import edu.rmit.service.IChatService;
import edu.rmit.service.IMessageService;
import edu.rmit.service.impl.CallBackServiceImpl;
import edu.rmit.service.impl.ChatServiceImpl;
import edu.rmit.util.PromotDialog;

/**
 * This class is to display the forum message list and the chat message list to
 * user, and also do the corresponding control initialize.
 * 
 * @author Thaw Zin
 * @version 1.0 
 * 
 */
@SuppressWarnings("serial")
public class LiveChatPanel extends UnicastRemoteObject {

	/**
	 * The label which display the welcome information.
	 */
	private JLabel labelWelcome;

	/**
	 * The panel which display the forum message.
	 */
	private MessageEditorPanel panelForum;

	/**
	 * The panel wich display the live chat message.
	 */
	private MessageEditorPanel panelLiveChat;

	/**
	 * The popup menu is to display when administrator using mouse right button
	 * click the message item, and show a delete menu item.
	 */
	private JPopupMenu forumPopMenu;

	/**
	 * The popup menu item is to display the delete message item when
	 * administrator using mouse right button click the message item.
	 */
	private JMenuItem forumMenuItem;

	/**
	 * The clieck instance which provide many corresponding service.
	 */
	private Client client;

	/**
	 * The groupId which the user is want to participant.
	 */
	private int groupId;

	/**
	 * The currently operate user.
	 */
	private User user;

	/**
	 * The frame object to initialize the window.
	 */
	private JFrame frame;

	/**
	 * This method is to register the current user into the corresponding group
	 * which the user currently selected.
	 */
	public void registerChatListener() {
		createFrame();
		try {
			IChatCallBackService callBackService = new CallBackServiceImpl(this);
			int status = client.getChatService().addChatListener(groupId,
					user.getUserName(), callBackService);
			if (status == ChatServiceImpl.ERR_GROUP_ID) {
				frame.dispose();
				String title = "Duplicate Enter Group";
				String reason = "Duplicate Enter Group!";
				PromotDialog.errorMessageBox(null, title, reason);
			} else {
				IMessageService messageService = client.getMessageService();
				List<Message> messages = messageService.getMessages(groupId);
				for (Message message : messages) {
					callBackService.addForumMessage(message.getSpeakerName(),
							message.getContent());
				}
			}

		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	/**
	 * This method is to create the window object, and the corresponding
	 * control.
	 */
	public void createFrame() {
		frame = new JFrame();
		frame.setTitle("Live Chat");
		frame.setSize(700, 600);
		frame.setLocation(100, 50);

		labelWelcome = new JLabel("Welcome:" + user.getUserName());
		Font font = new Font("", Font.BOLD, 20);
		labelWelcome.setFont(font);
		JPanel panelWelcome = new JPanel();
		panelWelcome.add(labelWelcome);
		panelWelcome.setBorder(BorderFactory.createTitledBorder(""));

		panelForum = new MessageEditorPanel();
		panelForum.setTitle("Forum");
		panelLiveChat = new MessageEditorPanel();
		panelLiveChat.setTitle("Live Chat");

		ListenerSendForumMsg listenerSendForumMsg = new ListenerSendForumMsg(
				client, panelForum, groupId, user.getUserName());
		ListenerSendLiveChatMsg listenerSendChatMsg = new ListenerSendLiveChatMsg(
				client, panelLiveChat, groupId, user.getUserName());

		panelForum.setListener(listenerSendForumMsg);
		panelLiveChat.setListener(listenerSendChatMsg);

		if (user.getRoleType() == RoleType.ADMIN) {
			forumPopMenu = new JPopupMenu();
			forumMenuItem = new JMenuItem("Delete This");
			forumPopMenu.add(forumMenuItem);
			JList forumList = panelForum.getListMessage();
			forumList.add(forumPopMenu);
			forumList.addMouseListener(new ListenerAddDeleteMenuItem());

			forumMenuItem.addActionListener(new ListenerDeleteForumMessage(
					groupId, forumList));
		}

		JPanel panelForumAndLiveChat = new JPanel();
		panelForumAndLiveChat.setLayout(new GridLayout(1, 2));
		panelForumAndLiveChat.add(panelForum);
		panelForumAndLiveChat.add(panelLiveChat);

		frame.setLayout(new BorderLayout());
		frame.add(panelWelcome, BorderLayout.NORTH);
		frame.add(panelForumAndLiveChat, BorderLayout.CENTER);
		frame.setVisible(true);

		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				try {
					client.getChatService().removeChatListener(groupId,
							user.getUserName(), "Leaving");
					frame.dispose();
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
		});
	}

	/**
	 * The constructor to initialize the corresponding control, and some
	 * corresponding value.
	 * 
	 * @param client The client instance of which provide the service.
	 * @param groupId
	 * @param user
	 * @throws RemoteException
	 */
	public LiveChatPanel(Client client, int groupId, User user)
			throws RemoteException {
		this.client = client;
		this.groupId = groupId;
		this.user = user;
		registerChatListener();
	}

	public MessageEditorPanel getPanelForum() {
		return panelForum;
	}

	public MessageEditorPanel getPanelLiveChat() {
		return panelLiveChat;
	}

	/**
	 * listenerone actionperformed if the sure button down.
	 * 
	 */
	class ListenerCreateGroup implements ActionListener {

		/**
		 * Changes the text of the label.
		 * 
		 * @param event
		 *            the event object.
		 */
		public void actionPerformed(ActionEvent event) {
			frame.dispose();
			new LoginPanel(client);
		}
	}

	/**
	 * listenerone actionperformed if the sure button down.
	 * 
	 */
	class ListenerLogout implements ActionListener {

		/**
		 * Changes the text of the label.
		 * 
		 * @param event
		 *            the event object.
		 */
		public void actionPerformed(ActionEvent event) {
			frame.dispose();
			new LoginPanel(client);
		}
	}

	class ListenerAddDeleteMenuItem extends MouseAdapter {
		@Override
		public void mouseClicked(MouseEvent e) {
			if (e.getButton() == 3) {
				forumPopMenu.show(panelForum.getListMessage(), e.getX(), e
						.getY());
			}
			super.mouseClicked(e);
		}
	}

	class ListenerDeleteForumMessage implements ActionListener {
		private int groupId;

		private JList messageList;

		public ListenerDeleteForumMessage(int groupId, JList messageList) {
			this.groupId = groupId;
			this.messageList = messageList;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				String title = "Delete Error";
				String reason = "";
				if (messageList.getModel().getSize() == 0) {
					reason = "Currently forum message is empty!";
					PromotDialog.errorMessageBox(null, title, reason);
					return;
				}
				int selectedIndex = messageList.getSelectedIndex();
				if (selectedIndex == -1) {
					reason = "Please choose an forum message to delete!";
					PromotDialog.errorMessageBox(null, title, reason);
					return;
				}
				IChatService chatService = client.getChatService();
				chatService.removeForumMessage(groupId, user.getUserName(),
						selectedIndex);

				IMessageService messageService = client.getMessageService();
				List<Message> messages = messageService.getMessages(groupId);
				Message message = messages.get(selectedIndex);
				messageService.deleteMessage(message.getId());
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
		}
	}

	public static void main(String a[]) {
		// Client client = new Client("127.0.0.1", 1099);
		// client.lookUpService();
		// new LiveChatPanel(client, "Qu Fanxin");
	}

}
